﻿using Caliburn.Micro;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.IOC.Core.Mediators;
using SlamDunk.MES.IAppService.DTOs.Outputs.ExecutionContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.PlanContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.QualityContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.ReportView.Models;
using SlamDunk.ValueObjects.Enums;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading.Tasks;
using LookViewModel = SlamDunk.MES.Client.ViewModels.WorkOrderInspection.LookViewModel;

namespace SlamDunk.MES.Client.ViewModels.ExecutionTrack
{
    /// <summary>
    /// 作业跟踪跟踪视图模型
    /// </summary>
    public class TrackViewModel : ScreenBase
    {
        #region # 字段及构造器

        /// <summary>
        /// 作业管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IExecutionContract> _executionContract;

        /// <summary>
        /// 质量管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IQualityContract> _qualityContract;

        /// <summary>
        /// 报表统计服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IReportContract> _reportContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public TrackViewModel(ServiceProxy<IExecutionContract> executionContract, ServiceProxy<IQualityContract> qualityContract, ServiceProxy<IReportContract> reportContract, IWindowManager windowManager)
        {
            this._executionContract = executionContract;
            this._qualityContract = qualityContract;
            this._reportContract = reportContract;
            this._windowManager = windowManager;
        }

        #endregion

        #region # 属性

        #region 作业计划 —— ExecutionPlanInfo ExecutionPlan
        /// <summary>
        /// 作业计划
        /// </summary>
        [DependencyProperty]
        public ExecutionPlanInfo ExecutionPlan { get; set; }
        #endregion

        #region 工单列表 —— ObservableCollection<WorkOrderInfo> WorkOrders
        /// <summary>
        /// 工单列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<WorkOrderInfo> WorkOrders { get; set; }
        #endregion

        #region 工单质量检查列表 —— ObservableCollection<WorkOrderInspectionInfo> WorkOrderInspections
        /// <summary>
        /// 工单质量检查列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<WorkOrderInspectionInfo> WorkOrderInspections { get; set; }
        #endregion

        #region 作业计划质量检查列表 —— ObservableCollection<ExecutionPlanInspectionInfo> ExecutionPlanInspections
        /// <summary>
        /// 作业计划质量检查列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<ExecutionPlanInspectionInfo> ExecutionPlanInspections { get; set; }
        #endregion

        #region 人员使用概要列表 —— ObservableCollection<PersonSummaryInfo> PersonUseSummaries
        /// <summary>
        /// 人员使用概要列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<PersonSummaryInfo> PersonUseSummaries { get; set; }
        #endregion

        #region 设备使用概要列表 —— ObservableCollection<EquipmentSummaryInfo> EquipmentUseSummaries
        /// <summary>
        /// 设备使用概要列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<EquipmentSummaryInfo> EquipmentUseSummaries { get; set; }
        #endregion

        #region 物料入库概要列表 —— ObservableCollection<MaterialSummaryInfo> MaterialStockInSummaries
        /// <summary>
        /// 物料入库概要列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialSummaryInfo> MaterialStockInSummaries { get; set; }
        #endregion

        #region 物料出库概要列表 —— ObservableCollection<MaterialSummaryInfo> MaterialStockOutSummaries
        /// <summary>
        /// 物料出库概要列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialSummaryInfo> MaterialStockOutSummaries { get; set; }
        #endregion

        #region 物料投入概要列表 —— ObservableCollection<MaterialSummaryInfo> MaterialInputSummaries
        /// <summary>
        /// 物料投入概要列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialSummaryInfo> MaterialInputSummaries { get; set; }
        #endregion

        #region 物料产出概要列表 —— ObservableCollection<MaterialSummaryInfo> MaterialOutputSummaries
        /// <summary>
        /// 物料投入概要列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialSummaryInfo> MaterialOutputSummaries { get; set; }
        #endregion

        #endregion

        #region # 方法

        //Initializations

        #region 加载 —— async Task Load(ExecutionPlanInfo executionPlan)
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="executionPlan">作业计划</param>
        public async Task Load(ExecutionPlanInfo executionPlan)
        {
            this.ExecutionPlan = executionPlan;

            IExecutionContract executionContract = this._executionContract.Channel;
            IQualityContract qualityContract = this._qualityContract.Channel;
            IReportContract reportContract = this._reportContract.Channel;

            //工单列表
            IEnumerable<WorkOrderInfo> workOrderInfos = await Task.Run(() => executionContract.GetWorkOrdersByPage(null, null, this.ExecutionPlan.Id, null, null, null, null, null, null, null, null, null, null, 1, int.MaxValue).Datas);
            this.WorkOrders = new ObservableCollection<WorkOrderInfo>(workOrderInfos.OrderBy(x => x.Sort));

            //工单质检列表
            IEnumerable<WorkOrderInspectionInfo> workOrderInspectionInfos = await Task.Run(() => qualityContract.GetWorkOrderInspectionsByPage(null, this.ExecutionPlan.Id, null, null, null, null, 1, int.MaxValue).Datas);
            this.WorkOrderInspections = new ObservableCollection<WorkOrderInspectionInfo>(workOrderInspectionInfos);

            //作业计划质检列表
            IEnumerable<ExecutionPlanInspectionInfo> executionPlanInspectionInfos = await Task.Run(() => qualityContract.GetExecutionPlanInspectionsByPage(null, this.ExecutionPlan.Id, null, null, null, 1, int.MaxValue).Datas);
            this.ExecutionPlanInspections = new ObservableCollection<ExecutionPlanInspectionInfo>(executionPlanInspectionInfos);

            //人员使用概要列表
            IEnumerable<PersonSummaryInfo> personUseSummaries = await Task.Run(() => reportContract.GetExecutionPlanPersonUseSummaries(this.ExecutionPlan.Id));
            this.PersonUseSummaries = new ObservableCollection<PersonSummaryInfo>(personUseSummaries);

            //设备使用概要列表
            IEnumerable<EquipmentSummaryInfo> equipmentUseSummaries = await Task.Run(() => reportContract.GetExecutionPlanEquipmentUseSummaries(this.ExecutionPlan.Id));
            this.EquipmentUseSummaries = new ObservableCollection<EquipmentSummaryInfo>(equipmentUseSummaries);

            //物料入库概要列表
            IEnumerable<MaterialSummaryInfo> materialStockInSummaries = await Task.Run(() => reportContract.GetExecutionPlanMaterialBoundSummaries(this.ExecutionPlan.Id, StockDirectionType.Input));
            this.MaterialStockInSummaries = new ObservableCollection<MaterialSummaryInfo>(materialStockInSummaries);

            //物料出库概要列表
            IEnumerable<MaterialSummaryInfo> materialStockOutSummaries = await Task.Run(() => reportContract.GetExecutionPlanMaterialBoundSummaries(this.ExecutionPlan.Id, StockDirectionType.Output));
            this.MaterialStockOutSummaries = new ObservableCollection<MaterialSummaryInfo>(materialStockOutSummaries);

            //物料投入概要列表
            IEnumerable<MaterialSummaryInfo> materialInputSummaries = await Task.Run(() => reportContract.GetExecutionPlanMaterialUseSummaries(this.ExecutionPlan.Id, MaterialDirectionType.Input));
            this.MaterialInputSummaries = new ObservableCollection<MaterialSummaryInfo>(materialInputSummaries);

            //物料产出概要列表
            IEnumerable<MaterialSummaryInfo> materialOutputSummaries = await Task.Run(() => reportContract.GetExecutionPlanMaterialUseSummaries(this.ExecutionPlan.Id, MaterialDirectionType.Output));
            this.MaterialOutputSummaries = new ObservableCollection<MaterialSummaryInfo>(materialOutputSummaries);
        }
        #endregion


        //Actions

        #region 查看工单 —— async void LookWorkOrder(WorkOrderInfo workOrder)
        /// <summary>
        /// 查看工单
        /// </summary>
        /// <param name="workOrder">工单</param>
        public async void LookWorkOrder(WorkOrderInfo workOrder)
        {
            Execution.LookViewModel viewModel = ResolveMediator.Resolve<Execution.LookViewModel>();
            await viewModel.Load(workOrder);
            await this._windowManager.ShowDialogAsync(viewModel);
        }
        #endregion

        #region 查看工单质量检查 —— async void LookWorkOrderInspection(WorkOrderInspectionInfo workOrderInspection)
        /// <summary>
        /// 查看工单质量检查
        /// </summary>
        /// <param name="workOrderInspection">工单质量检查</param>
        public async void LookWorkOrderInspection(WorkOrderInspectionInfo workOrderInspection)
        {
            LookViewModel viewModel = ResolveMediator.Resolve<LookViewModel>();
            await viewModel.Load(workOrderInspection);
            await this._windowManager.ShowDialogAsync(viewModel);
        }
        #endregion

        #region 查看作业计划质量检查 —— async void LookExecutionPlanInspection(ExecutionPlanInspectionInfo...
        /// <summary>
        /// 查看作业计划质量检查
        /// </summary>
        /// <param name="executionPlanInspection">作业计划质量检查</param>
        public async void LookExecutionPlanInspection(ExecutionPlanInspectionInfo executionPlanInspection)
        {
            ExecutionPlanInspection.LookViewModel viewModel = ResolveMediator.Resolve<ExecutionPlanInspection.LookViewModel>();
            await viewModel.Load(executionPlanInspection);
            await this._windowManager.ShowDialogAsync(viewModel);
        }
        #endregion

        #endregion
    }
}
